#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# report_generator.py - 优化报告生成模块

import json
import os
import re
import requests
from datetime import datetime
from typing import Dict, Any
from .web_data_collector import WebDataCollector
from .cve_matcher import CVEMatcher
from .anomaly_detector import AnomalyDetector
from .config_optimizer import ConfigOptimizer
import yaml


class ReportGenerator:
    def __init__(self, api_key: str, api_url: str, model_name: str, config_adapter, cve_result=None):
        """初始化报告生成器"""
        self.api_key = api_key
        self.api_url = api_url
        self.model_name = model_name
        self.config_adapter = config_adapter
        self.cve_result = cve_result
        self.report = {
            "generated_at": datetime.now().isoformat(),
            "system_info": {},
            "cve_vulnerabilities": {},
            "anomalies": {},
            "config_issues": {},
            "performance_bottlenecks": {},
            "optimization_recommendations": []
        }

    def _call_llm_model(self, prompt: str) -> str:
        """调用大语言模型API生成优化建议"""
        # 获取配置适配器的设置
        headers = {
            "Content-Type": "application/json"
        }
        
        # 添加授权头（如果需要）
        auth_headers = self.config_adapter.get_authorization_header()
        headers.update(auth_headers)

        payload = {
            "model": self.model_name,
            "messages": [
                {"role": "system",
                 "content": "你是银河麒麟系统的Apache服务器优化专家，需要基于检测结果提供专业、可操作的修复建议。"},
                {"role": "user", "content": prompt}
            ],
            "temperature": self.config_adapter.get_temperature(),
            "max_tokens": self.config_adapter.get_max_tokens()
        }

        try:
            # 获取超时配置，本地模型需要更长时间
            timeout = self.config_adapter.config.get('timeout', 300)
            response = requests.post(
                self.api_url,
                headers=headers,
                json=payload,
                timeout=timeout
            )
            response.raise_for_status()
            result = response.json()
            
            # 处理不同API响应格式
            if "choices" in result and len(result["choices"]) > 0:
                return result["choices"][0]["message"]["content"]
            elif "message" in result:
                return result["message"]["content"]
            else:
                return str(result)
                
        except Exception as e:
            print(f"调用LLM API失败: {str(e)}")
            return f"生成建议失败: {str(e)}"

    def collect_all_data(self) -> None:
        """收集所有检测数据"""
        # 1. 收集Web基础信息
        collector = WebDataCollector()
        self.report["system_info"] = collector.collect_web_info()
        collector.save_to_file()

        # 2. 检测CVE漏洞
        matcher = CVEMatcher()
        web_version = self.report["system_info"].get("version")
        if web_version:
            self.report["cve_vulnerabilities"] = matcher.get_web_vulnerabilities(web_version)
        else:
            self.report["cve_vulnerabilities"] = {"status": "unknown", "message": "无法获取Web版本"}

        # 3. 检测异常模式
        detector = AnomalyDetector()
        self.report["anomalies"] = detector.detect_anomalies()

        # 4. 检测配置问题和性能瓶颈
        optimizer = ConfigOptimizer()
        optimizer.collect_performance_metrics()
        self.report["config_issues"] = optimizer.evaluate_config()
        self.report["performance_bottlenecks"] = optimizer.detect_performance_bottlenecks()

    def generate_recommendations(self) -> None:
        """生成优化建议"""
        # 构建提示词，明确要求分类结构
        prompt = f"""基于以下web服务器的检测结果，为银河麒麟系统生成详细的优化建议:

1. 系统信息:
{json.dumps(self.report['system_info'], indent=2, ensure_ascii=False)}

2. CVE漏洞情况:
{json.dumps(self.report['cve_vulnerabilities'], indent=2, ensure_ascii=False)}

3. 异常模式检测:
{json.dumps(self.report['anomalies'], indent=2, ensure_ascii=False)}

4. 配置问题:
{json.dumps(self.report['config_issues'], indent=2, ensure_ascii=False)}

5. 性能瓶颈:
{json.dumps(self.report['performance_bottlenecks'], indent=2, ensure_ascii=False)}

请严格按以下结构生成建议，每个部分用标题开始，内容用项目符号列出:
1. 安全漏洞修复建议（优先处理）
2. 异常问题解决建议
3. 配置优化步骤
4. 性能提升方案
5. 操作注意事项

建议需要符合银河麒麟系统的特性，针对web服务器提供具体、可执行的命令和配置修改方法。"""

        # 调用大模型生成建议
        self.report["optimization_recommendations"] = self._call_llm_model(prompt)

    def _format_recommendations(self, recommendations: str) -> str:
        """格式化优化建议，将不同类别转换为带样式的HTML区块"""
        # 移除多余符号
        recommendations = recommendations.replace("*", "").replace("`", "")

        # 定义建议类别和对应的样式类
        categories = {
            "安全漏洞修复建议（优先处理）": "security",
            "异常问题解决建议": "anomaly",
            "配置优化步骤": "configuration",
            "性能提升方案": "performance",
            "操作注意事项": "notes"
        }

        # 分割建议为各个类别部分
        html_sections = []
        current_section = None
        current_content = []

        # 使用正则表达式匹配标题行
        lines = recommendations.split('\n')
        for line in lines:
            # 检查是否是类别标题行
            matched = False
            for category in categories:
                if category in line:
                    if current_section:
                        # 保存当前部分
                        html_sections.append(self._create_section(current_section, current_content))
                    current_section = category
                    current_content = []
                    matched = True
                    break
            if not matched and current_section:
                # 处理列表项
                if line.startswith('- '):
                    current_content.append(line[2:].strip())
                elif line.strip():
                    current_content.append(line.strip())

        # 添加最后一个部分
        if current_section and current_content:
            html_sections.append(self._create_section(current_section, current_content))

        # 组合所有部分
        return ''.join(html_sections)

    def _create_section(self, title: str, items: list) -> str:
        """创建单个建议类别的HTML区块"""
        categories = {
            "安全漏洞修复建议（优先处理）": "security",
            "异常问题解决建议": "anomaly",
            "配置优化步骤": "configuration",
            "性能提升方案": "performance",
            "操作注意事项": "notes"
        }

        style_class = categories.get(title, "general")
        icon_classes = {
            "security": "fa-shield",
            "anomaly": "fa-exclamation-triangle",
            "configuration": "fa-cogs",
            "performance": "fa-tachometer",
            "notes": "fa-info-circle",
            "general": "fa-list"
        }
        icon = icon_classes.get(style_class, "fa-list")

        items_html = ''.join([f'<li>{item}</li>' for item in items if item])

        return f'''
        <div class="recommendation-section {style_class}">
            <h3><i class="fa {icon}"></i> {title}</h3>
            <ul>{items_html}</ul>
        </div>
        '''

    def _generate_html_content(self) -> str:
        """生成HTML报告内容，排除system_info中的modules字段"""
        # 转换并格式化建议为HTML
        recommendations = self.report["optimization_recommendations"]
        formatted_recommendations = self._format_recommendations(recommendations)

        # 系统信息表格（排除modules字段）
        system_info = self.report["system_info"]
        system_info_html = "<table class='system-info'>"
        for key, value in system_info.items():
            # 跳过modules字段
            if key.lower() == "modules":
                continue
            # 处理其他字段
            system_info_html += f"<tr><th>{key}</th><td>{value}</td></tr>"
        system_info_html += "</table>"

        html_content = f"""<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>web服务器优化报告 - {self.report['generated_at']}</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
    <style>
        :root {{
            --primary-color: #2c3e50;
            --secondary-color: #3498db;
            --security-color: #e74c3c;
            --anomaly-color: #f39c12;
            --configuration-color: #27ae60;
            --performance-color: #9b59b6;
            --notes-color: #1abc9c;
            --light-bg: #f8f9fa;
            --card-shadow: 0 2px 10px rgba(0,0,0,0.08);
            --section-padding: 30px;
        }}

        body {{
            font-family: "Microsoft YaHei", "Segoe UI", sans-serif;
            line-height: 1.8;
            margin: 0;
            padding: 0;
            background-color: var(--light-bg);
            color: #333;
        }}

        .container {{
            max-width: 1200px;
            margin: 0 auto;
            background-color: white;
            padding: 40px;
            box-shadow: var(--card-shadow);
            margin-top: 30px;
            margin-bottom: 30px;
            border-radius: 8px;
        }}

        header {{
            text-align: center;
            margin-bottom: 40px;
            padding-bottom: 25px;
            border-bottom: 3px solid var(--primary-color);
        }}

        h1 {{
            color: var(--primary-color);
            margin: 0 0 15px 0;
            font-size: 2.2rem;
        }}

        .generation-time {{
            color: #666;
            font-size: 0.95rem;
            font-style: italic;
        }}

        .section {{
            margin-bottom: 40px;
            padding: var(--section-padding);
            background-color: #fff;
            border-radius: 8px;
            box-shadow: var(--card-shadow);
            transition: transform 0.3s ease;
        }}

        .section:hover {{
            transform: translateY(-5px);
        }}

        .section h2 {{
            color: var(--secondary-color);
            border-left: 4px solid var(--secondary-color);
            padding-left: 15px;
            margin-top: 0;
            margin-bottom: 20px;
            font-size: 1.6rem;
            display: flex;
            align-items: center;
        }}

        .section h2 i {{
            margin-right: 10px;
        }}

        .system-info {{
            width: 100%;
            border-collapse: collapse;
            margin: 20px 0;
        }}

        .system-info th, .system-info td {{
            border: 1px solid #e0e0e0;
            padding: 12px 15px;
            text-align: left;
        }}

        .system-info th {{
            background-color: #f5f7fa;
            font-weight: 600;
            color: var(--primary-color);
            width: 30%;
        }}

        .system-info tr:nth-child(even) {{
            background-color: #fafafa;
        }}

        .system-info tr:hover {{
            background-color: #f0f7ff;
        }}

        .recommendations {{
            background-color: #f9f9f9;
            padding: 20px;
            border-radius: 8px;
        }}

        .recommendation-section {{
            margin-bottom: 30px;
            padding: 20px;
            border-radius: 6px;
            background-color: white;
            box-shadow: 0 1px 4px rgba(0,0,0,0.05);
        }}

        .recommendation-section h3 {{
            margin-top: 0;
            margin-bottom: 15px;
            font-size: 1.3rem;
            padding-bottom: 10px;
            border-bottom: 2px solid;
            display: flex;
            align-items: center;
        }}

        .recommendation-section h3 i {{
            margin-right: 10px;
            font-size: 1.2em;
        }}

        .recommendation-section ul {{
            padding-left: 25px;
            margin-top: 10px;
            margin-bottom: 0;
        }}

        .recommendation-section li {{
            margin-bottom: 12px;
            position: relative;
            padding-left: 5px;
        }}

        .recommendation-section li:last-child {{
            margin-bottom: 0;
        }}

        .recommendation-section li:before {{
            content: "•";
            font-weight: bold;
            position: absolute;
            left: -15px;
        }}

        /* 不同类别的样式 */
        .security h3 {{
            color: var(--security-color);
            border-color: var(--security-color);
        }}

        .security li:before {{
            color: var(--security-color);
        }}

        .anomaly h3 {{
            color: var(--anomaly-color);
            border-color: var(--anomaly-color);
        }}

        .anomaly li:before {{
            color: var(--anomaly-color);
        }}

        .configuration h3 {{
            color: var(--configuration-color);
            border-color: var(--configuration-color);
        }}

        .configuration li:before {{
            color: var(--configuration-color);
        }}

        .performance h3 {{
            color: var(--performance-color);
            border-color: var(--performance-color);
        }}

        .performance li:before {{
            color: var(--performance-color);
        }}

        .notes h3 {{
            color: var(--notes-color);
            border-color: var(--notes-color);
        }}

        .notes li:before {{
            color: var(--notes-color);
        }}

        .log-files {{
            background-color: #f0f7ff;
            padding: 15px;
            border-radius: 6px;
            border-left: 3px solid var(--secondary-color);
            font-family: monospace;
            word-break: break-all;
        }}

        footer {{
            text-align: center;
            margin-top: 50px;
            padding-top: 20px;
            border-top: 1px solid #e0e0e0;
            color: #7f8c8d;
            font-size: 0.9rem;
        }}

        @media (max-width: 768px) {{
            .container {{
                padding: 20px;
            }}

            .section {{
                padding: 20px;
            }}

            h1 {{
                font-size: 1.8rem;
            }}

            .system-info th {{
                width: 40%;
            }}
        }}
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>银河麒麟系统 - web服务器优化报告</h1>
            <p class="generation-time">生成时间: {self.report['generated_at']}</p>
        </header>

        <div class="section">
            <h2><i class="fa fa-server"></i> 系统信息</h2>
            {system_info_html}
        </div>

        <div class="section">
            <h2><i class="fa fa-file-lines"></i> 检测到的日志文件</h2>
            <div class="log-files">
                {', '.join(self.report['anomalies'].get('log_files_checked', [])) or '未检测到日志文件'}
            </div>
        </div>

        <div class="section">
            <h2><i class="fa fa-lightbulb"></i> 优化建议</h2>
            <div class="recommendations">
                {formatted_recommendations}
            </div>
        </div>

        <footer>
            <p>本报告由银河麒麟系统管家工具自动生成 | 仅供参考，实际操作请谨慎</p>
        </footer>
    </div>
</body>
</html>"""
        return html_content

    def save_report(self, output_dir: str = "data/DefectIdentification_data/web_data") -> str:
        """保存报告到文件（同时生成JSON和HTML格式）"""
        os.makedirs(output_dir, exist_ok=True)
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')

        # 保存JSON格式
        json_filename = os.path.join(output_dir, f"apache_optimization_report_{timestamp}.json")
        # 先创建文件
        with open(json_filename, 'x') as f:
            pass  # 创建空文件
        # 再写入内容
        with open(json_filename, 'w') as f:
            json.dump(self.report, f, indent=2, ensure_ascii=False)

        # 保存HTML格式
        html_filename = os.path.join(output_dir, f"apache_optimization_report_{timestamp}.html")
        # 先创建文件
        with open(html_filename, 'x', encoding='utf-8') as f:
            pass  # 创建空文件
        # 再写入内容
        with open(html_filename, 'w', encoding='utf-8') as f:
            f.write(self._generate_html_content())

        return html_filename  # 返回HTML报告路径

    def generate_full_report(self) -> str:
        """生成完整报告"""
        print("开始收集系统信息和检测数据...")
        self.collect_all_data()

        print("生成优化建议...")
        self.generate_recommendations()

        print("保存报告...")
        report_path = self.save_report()
        print(f"完整HTML报告已生成: {report_path}")
        return report_path


if __name__ == "__main__":
    # 使用新的配置适配器
    from config_adapter import ConfigAdapter
    
    config_adapter = ConfigAdapter()
    
    # 从配置适配器获取API配置
    api_key = config_adapter.get_api_key()
    api_url = config_adapter.get_api_url()
    model_name = config_adapter.get_model()

    # 生成报告
    generator = ReportGenerator(api_key, api_url, model_name, config_adapter)
    generator.generate_full_report()